//
// ModuleManager.cpp
// Usage: Manage all startup-loaded kernel modules
// CreateDate: 2009-04-09
// Author: MaJiuyue
//
#include <bootutil.h>
#include "ModuleManager.h"
#include "ElfParser.h"

CModuleManager::CModuleManager(addr_t mods_addr, int mods_count)
{
	for(int i=0; i<mods_count; i++)
		if(!AddModule(&((module_t *)mods_addr)[i]))
			panic("Startup-module add failed.");	

	// Create `ModuleManager' resource
	Resource * res = new Resource(this);
	ResourceManager.CreateResource(res, ServiceCallInterface::ModuleManager::ResourceName);
	res->RegisterInterface(
		(Resource::CallInterface1)&CModuleManager::GetModule,
		ServiceCallInterface::ModuleManager::SCIID_GetModule
	);
	res->RegisterInterface(
		(Resource::CallInterface1)&CModuleManager::AddModule,
		ServiceCallInterface::ModuleManager::SCIID_AddModule
	);
	res->RegisterInterface(
		(Resource::CallInterface1)&CModuleManager::DelModule,
		ServiceCallInterface::ModuleManager::SCIID_DelModule
	);
	res->RegisterInterface(
		(Resource::CallInterface1)&CModuleManager::GetModuleByIndex,
		ServiceCallInterface::ModuleManager::SCIID_GetModuleByIndex
	);
	res->RegisterInterface(
		(Resource::CallInterface0)&CModuleManager::GetModuleCount,
		ServiceCallInterface::ModuleManager::SCIID_GetModuleCount
	);
}

CModuleManager::~CModuleManager()
{
	for(int i=0; i<m_KernelModules.length(); i++)
	{
		Module * mod = m_KernelModules.getByIndex(i);
		delete mod;
	}
}

bool CModuleManager::AddModule(module_t *ko)
{
	// If already exist modules have this name, return false
	if(m_KernelModules.lookup((char *)ko->string))
		return false;

	// Create a new module descriptor
	Module * mod = new Module(
		(char *)ko->string,
		(addr_t)ko->mod_start,
		(size_t)(ko->mod_end-ko->mod_start+1)
	);
	
	// Add it to module list
	m_KernelModules.add(String((char *)ko->string), mod);

	kprintf("Add kernel module: %s.\n", (char *)ko->string);
	
	// return OK
	return true;
}

